package gitobject;



import sha1.SHA1;
import java.io.Serializable;
import zlib.ZLibUtils;
import fileoperation.FileReader;

import java.io.*;
import java.lang.reflect.Array;
import java.security.MessageDigest;
import java.util.*;


public class Tree extends GitObject{
    protected ArrayList<GitObject> treeList;	//GitObjects in tree

    public ArrayList<GitObject> getTreeList(){
        return treeList;
    }

    public Tree(){}
    
    /**
     * Constructor
     * @param file
     * @throws Exception
     */
    public Tree(File file) throws Exception {
        this.treeList = new ArrayList<>();
        this.fmt = "tree";
        this.mode = "040000";
        this.value = "";
        this.key = genKey(file);
        writeObject();
    }

    /**
     * Deserialize a tree object with treeId and its path.
     * 反序列化
     * @param Id
     * @param Id
     * @throws IOException
     */
    public static Tree deserialize(String Id) throws IOException {
        try{
            /**
             * Todo: Add your code here.
             */
            Tree tree = new Tree();
            FileInputStream fis = new FileInputStream("D:/tes/.jit/objects" + File.separator + Id);
            ObjectInputStream ois = new ObjectInputStream(fis);
            tree = (Tree)ois.readObject();
            ois.close();
            return tree;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
        /* Todo: You should delete the return statement before you start. */
        
    }


    /**
     * Sort the files in a certain order. You should consider whether it's a file or a directory.
     * 按文件名称排序
     * @param fs
     * @return List
     */
    public List sortFile(File[] fs){
        List fileList = Arrays.asList(fs);
        Collections.sort(fileList, new Comparator<File>() {
            @Override //表示重写方法
            public int compare(File o1, File o2) {
                /* Todo: Add your code here. */
                if (o1.isDirectory() && o2.isFile())
                    return 1;
                if (o1.isFile() && o2.isDirectory())
                    return -1;
                return o1.getName().compareTo(o2.getName());

            }
        });
        return fileList;
    }

    /**
     * Generate the key of a tree object.
     * 获取数的key值
     * @param dir
     * @return String
     * @throws Exception
     * 树的value值记录文件的标识、hash值、文件名以及子文件夹的value
     */
    public String genKey(File dir) throws Exception{
        /* Todo: Add your code here. */
        File[] fs =dir.listFiles();
        List<File> fileList = sortFile(fs);
        StringBuilder stringBuilder=new StringBuilder();
        for (File file : fileList) {
            if (file.isFile()) {
                stringBuilder.append("040000 blob " + SHA1.getHash(file) + " " + file.getName() + '\n');
            }else if (file.isDirectory()){
                stringBuilder.append("040000 tree " + genKey(file) + " " + file.getName()+ '\n');
                
            }
        }

        String value="040000 tree " + stringBuilder.toString() + " " + dir.getName();
        key = SHA1.getHash(value);
        return key;
    }

    @Override
    public String toString(){
        return "040000 tree " + key + value;
    }

}
